<?php 
namespace common\bot;
defined('STDIN') or define('STDIN', fopen("php://stdin","r"));

use waylaidwanderer\SteamCommunity\SteamCommunity;
use waylaidwanderer\SteamCommunity\Enum\LoginResult;
use common\model\sell66\Bot;
use think\Cache;
class LoginService{
	
	public static $instance = null;
	const  BOT_LIST_PRE = 'bot_list_key_';
	
	private function __construct(){
	}
	public static function getInstance(){
		if(self::$instance == null){
			self::$instance = new self();
		}
		return self::$instance;
	}
	
	
	public function initApiKey($config){
		$botModel = new Bot();
		$id = $config['id'];
		$steam = new SteamCommunity($config, dirname(__FILE__));
		$loginResult = $steam->doLogin();
		while ($loginResult != LoginResult::LoginOkay) {
			if ($loginResult == LoginResult::Need2FA) {
				if ($steam->mobileAuth() == null) {
					$authCode = $this->ask('Enter 2FA code: ');
					$steam->setTwoFactorCode($authCode);
				} else {
					$authCode = $steam->mobileAuth()->steamGuard()->generateSteamGuardCode();
					$steam->setTwoFactorCode($authCode);
					$this->writeLine('Generated Steam Guard code: ' . $authCode);
				}
				$loginResult = $steam->doLogin();
			} else if ($loginResult == LoginResult::NeedEmail) {
				$authCode = ask('Enter Steam Guard code from email: ');
				$steam->setEmailCode($authCode);
				$loginResult = $steam->doLogin();
			} else if ($loginResult == LoginResult::NeedCaptcha) {
				$captchaCode = ask('Enter captcha (' . $steam->getCaptchaLink() . '): ');
				$steam->setCaptchaText($captchaCode);
				$loginResult = $steam->doLogin();
			} else {
				break;
			}
			$this->writeLine("Login result: {$loginResult}.");
		}
		$apiKey =  $steam->getApiKey();
		if(empty($apiKey)){
			$apiKey = $steam->mobileAuth()->steamCommunity()->getApiKey();
		}
		Bot::where(['id'=>$id])->update(['apikey'=>$apiKey]);
	}
	
	public function dologin($config){
		$botModel = new Bot();
		$id = $config['id'];
		$botId = $config['botId'];
		try {
			$steam = new SteamCommunity($config, dirname(__FILE__));
			$loginResult = $steam->doLogin();
			while ($loginResult != LoginResult::LoginOkay) {
				if ($loginResult == LoginResult::Need2FA) {
					if ($steam->mobileAuth() == null) {
						$authCode = $this->ask('Enter 2FA code: ');
						$steam->setTwoFactorCode($authCode);
					} else {
						$authCode = $steam->mobileAuth()->steamGuard()->generateSteamGuardCode();
						$steam->setTwoFactorCode($authCode);
						$this->writeLine('Generated Steam Guard code: ' . $authCode);
					}
					$loginResult = $steam->doLogin();
				} else if ($loginResult == LoginResult::NeedEmail) {
					$authCode = ask('Enter Steam Guard code from email: ');
					$steam->setEmailCode($authCode);
					$loginResult = $steam->doLogin();
				} else if ($loginResult == LoginResult::NeedCaptcha) {
					$captchaCode = ask('Enter captcha (' . $steam->getCaptchaLink() . '): ');
					$steam->setCaptchaText($captchaCode);
					$loginResult = $steam->doLogin();
				} else {
					break;
				}
				$this->writeLine("Login result: {$loginResult}.");
			}
			$botModel->setSteam($steam);
			if($steam->isLoggedIn()){
				Bot::saveBotLogin($id,true);
				$this->setBot($botId, $steam, 108000);
				return $botModel;
			}else{
				Bot::saveBotLogin($id,false);
				return false;
			}
		} catch (\Exception $e) {
			Bot::saveBotLogin($id,false);
			return false;
		}
	}
	
	public function setBot($botAccount,$robot,$expire=86400){
		$key = self::BOT_LIST_PRE . $botAccount;
		Cache::store('redis')->set($key, serialize($robot),$expire);
	}
	
	public function getBot($botAccount){
		$key = self::BOT_LIST_PRE . $botAccount;
		return unserialize(Cache::store('redis')->get($key));
	}
	
	private function writeLine($line)
	{
		echo $line.PHP_EOL;
	}
	
	private function ask($prompt = '')
	{
		echo $prompt;
		return rtrim(fgets(STDIN), "\n");
	}
	
}